
#pragma once

#include "registration_begin.h"

namespace tools
{
    class Variant;

    namespace variant_detail
    {

//-----------------------------------------------------------------------------------------
        struct VariantTypes
        {
            typedef int8_t                        I8;
            typedef int16_t                       I16;
            typedef int32_t                       I32;
            typedef int64_t                       I64;
            typedef uint8_t                       U8;
            typedef uint16_t                      U16;
            typedef uint32_t                      U32;
            typedef uint64_t                      U64;
            typedef float                         F32;
            typedef double                        F64;
            typedef char                          Byte;
            typedef wchar_t                       WChar;
            typedef ::std::string                 Str;
            typedef ::std::wstring                WStr;
            typedef ::std::vector<Byte>           Blob;
            typedef ::std::list<Variant>          List;
            typedef ::std::vector<Variant>        Vec;
            typedef ::std::map<Str,Variant>       Map;
            typedef ::std::pair<Str,Variant>      Record;
            typedef ::std::vector<Record>         Records;

            static_assert(sizeof(Byte) == 1, "Bad type size.");
            static_assert(sizeof(I8)   == 1, "Bad type size.");
            static_assert(sizeof(U8)   == 1, "Bad type size.");
            static_assert(sizeof(I16)  == 2, "Bad type size.");
            static_assert(sizeof(U16)  == 2, "Bad type size.");
            static_assert(sizeof(I32)  == 4, "Bad type size.");
            static_assert(sizeof(U32)  == 4, "Bad type size.");
            static_assert(sizeof(I64)  == 8, "Bad type size.");
            static_assert(sizeof(U64)  == 8, "Bad type size.");
            static_assert(sizeof(F32)  == 4, "Bad type size.");
            static_assert(sizeof(F64)  == 8, "Bad type size.");

            static_assert(sizeof(Str::value_type)  == 1, "Bad size of char"    );
            static_assert(sizeof(WStr::value_type) == 2, "Bad size of wchar_t" );
        };
        typedef VariantTypes V;
//-----------------------------------------------------------------------------------------
        enum eTYPE
        {
            eNULL,
            eBOOL,
            eBYTE,
            eWCHAR,
            eI8,
            eI16,
            eI32,
            eI64,
            eU8,
            eU16,
            eU32,
            eU64,
            eF32,
            eF64,
            eSTRING,
            eWSTRING,
            eBLOB,
            eRECORD,
            eRECORDS,
            eMAP,
            eVECTOR,
            eLIST,
            eEND_TYPE
        };

//-----------------------------------------------------------------------------------------
        //-- table   [   type    ][ enum-id ][   category    ][  type-name  ][ work-status ]
        REGISTER_TYPE( bool      ,  eBOOL    ,  ePRIMITIVE   ,    "BOOL"     ,   ENABLED   );
        REGISTER_TYPE( V::I8     ,  eI8      ,  ePRIMITIVE   ,    "INT8"     ,   ENABLED   );
        REGISTER_TYPE( V::I16    ,  eI16     ,  ePRIMITIVE   ,    "INT16"    ,   ENABLED   );
        REGISTER_TYPE( V::I32    ,  eI32     ,  ePRIMITIVE   ,    "INT32"    ,   ENABLED   );
        REGISTER_TYPE( V::I64    ,  eI64     ,  ePRIMITIVE   ,    "INT64"    ,   ENABLED   );
        REGISTER_TYPE( V::U8     ,  eU8      ,  ePRIMITIVE   ,    "UINT8"    ,   ENABLED   );
        REGISTER_TYPE( V::U16    ,  eU16     ,  ePRIMITIVE   ,    "UINT16"   ,   ENABLED   );
        REGISTER_TYPE( V::U32    ,  eU32     ,  ePRIMITIVE   ,    "UINT32"   ,   ENABLED   );
        REGISTER_TYPE( V::U64    ,  eU64     ,  ePRIMITIVE   ,    "UINT64"   ,   ENABLED   );
        REGISTER_TYPE( V::F32    ,  eF32     ,  ePRIMITIVE   ,    "FLOAT32"  ,   ENABLED   );
        REGISTER_TYPE( V::F64    ,  eF64     ,  ePRIMITIVE   ,    "FLOAT64"  ,   ENABLED   );
        REGISTER_TYPE( V::Byte   ,  eBYTE    ,  ePRIMITIVE   ,    "BYTE"     ,   ENABLED   );
        REGISTER_TYPE( V::WChar  ,  eWCHAR   ,  ePRIMITIVE   ,    "WCHAR"    ,   ENABLED   );
        REGISTER_TYPE( V::Str    ,  eSTRING  ,  ePRIMITIVE   ,    "STRING"   ,   ENABLED   );
        REGISTER_TYPE( V::WStr   ,  eWSTRING ,  ePRIMITIVE   ,    "WSTRING"  ,   ENABLED   );
        REGISTER_TYPE( V::Blob   ,  eBLOB    ,  ePRIMITIVE   ,    "BLOB"     ,   ENABLED   );
        REGISTER_TYPE( V::Record ,  eRECORD  ,  eKEY_VARIANT ,    "RECORD"   ,   ENABLED   );
        REGISTER_TYPE( V::Records,  eRECORDS ,  eASSOCIATIVE ,    "RECORDS"  ,   ENABLED   );
        REGISTER_TYPE( V::Map    ,  eMAP     ,  eASSOCIATIVE ,    "MAP"      ,   ENABLED   );
        REGISTER_TYPE( V::Vec    ,  eVECTOR  ,  eLINEAR      ,    "VECTOR"   ,   ENABLED   );
        REGISTER_TYPE( V::List   ,  eLIST    ,  eLINEAR      ,    "LIST"     ,   ENABLED   );
        #undef REGISTER_TYPE
//-----------------------------------------------------------------------------------------

    }//namespace value_detail
}//namespace tools

#include "registration_end.h"
